
#include "software_timer.h"
#include <string.h>

void software_timer_group_init(SoftwareTimer_Group_STRUCT* software_timer_group,
                               uint8_t software_timer_group_len,
                               SoftwareTimer_STRUCT* software_timer_group_space)
{
	software_timer_group->len = software_timer_group_len;
    software_timer_group->count = 0;
    software_timer_group->software_timer = software_timer_group_space;
	for(; software_timer_group_len > 0; software_timer_group_len--){
		software_timer_group_space[software_timer_group_len-1].count = 0;
		software_timer_group_space[software_timer_group_len-1].overtime = 0;
		software_timer_group_space[software_timer_group_len-1].running = 0;
		software_timer_group_space[software_timer_group_len-1].timeout = 0;
	}
}

void software_timer_group_handler(SoftwareTimer_Group_STRUCT* software_timer_group,
                                  uint16_t tick_time)
{
	uint8_t i;
	SoftwareTimer_STRUCT* sw_timer = software_timer_group->software_timer;
	if(tick_time > 0){
		for (i = 0; i < software_timer_group->count; i++) {
			if ((sw_timer[i].running)&&(sw_timer[i].overtime == 0)) {
				if(sw_timer[i].count >= tick_time){
					sw_timer[i].count -= tick_time;
				}
				else{
					sw_timer[i].count = 0;
				}
				if (sw_timer[i].count == 0) {
					sw_timer[i].count = sw_timer[i].timeout;
					sw_timer[i].overtime = 1;
				}
			}
		}
	}
}

uint16_t software_timer_group_find_minimum_time(SoftwareTimer_Group_STRUCT* software_timer_group)
{
	uint8_t i;
    uint16_t minimum_time = 0xffff;
	SoftwareTimer_STRUCT* sw_timer = software_timer_group->software_timer;

	for (i = 0; i < software_timer_group->count; i++) {
		if (sw_timer[i].running) {
			if(minimum_time > sw_timer[i].count){
				minimum_time =  sw_timer[i].count;
			}
		}
	}

    return minimum_time;
}

uint8_t software_timer_group_check_running_all(SoftwareTimer_Group_STRUCT* software_timer_group) {

	uint8_t i;
    SoftwareTimer_STRUCT* sw_timer = software_timer_group->software_timer;
	for (i = 0; i < software_timer_group->count; i++) {
		if (sw_timer[i].running) {
			return 1;
		}
	}

	return 0;
}

SoftwareTimer_STRUCT*  software_timer_create(SoftwareTimer_Group_STRUCT* software_timer_group,
                              uint16_t timeout)
{
    SoftwareTimer_STRUCT* sw_timer = software_timer_group->software_timer;
	if(software_timer_group->count < software_timer_group->len){
		sw_timer[software_timer_group->count].count = timeout;
		sw_timer[software_timer_group->count].timeout = timeout;
		sw_timer[software_timer_group->count].running = 0;
		sw_timer[software_timer_group->count].overtime = 0;
        sw_timer = &(sw_timer[software_timer_group->count]);
        software_timer_group->count++;
        return sw_timer;
    }
    else{
        return 0;
    }
}

uint8_t software_timer_check_running(SoftwareTimer_STRUCT* software_timer) {
    if(software_timer != 0){
        return software_timer->running;
    }
    else{
        return 0;
    }
}

uint8_t software_timer_check_overtime(SoftwareTimer_STRUCT* software_timer) {
    if(software_timer == 0){
        return 0;
    }
	if(software_timer->overtime == 1){
		software_timer->overtime = 0;
		return 1;
	}
	else{
		return 0;
	}
}

uint8_t software_timer_start(SoftwareTimer_STRUCT* software_timer) {
    if(software_timer == 0){
        return 0;
    }
	software_timer->running = 1;
	return 1;
}

uint8_t software_timer_stop(SoftwareTimer_STRUCT* software_timer) {
    if(software_timer == 0){
        return 0;
    }
	software_timer->running = 0;
	return 1;
}

uint8_t software_timer_restart(SoftwareTimer_STRUCT* software_timer) {
    if(software_timer == 0){
        return 0;
    }
	software_timer->count = software_timer->timeout;
	software_timer->running = 1;
	return 1;
}

uint8_t software_timer_set_timeout(SoftwareTimer_STRUCT* software_timer, uint16_t timeout) {
    if(software_timer == 0){
        return 0;
    }
	software_timer->timeout = timeout;
	return 1;
}

